package 栈;


import java.util.ArrayDeque;
import java.util.Deque;

/**
 * 基本计算器二: https://leetcode.cn/problems/basic-calculator-ii/description/
 */
public class likou277 {

    class Solution {
        // 练习
        public int calculate(String s1) {
            // 利用一个双端队列 deque, 先计算乘除
            Deque<Integer> stack = new ArrayDeque<>();
            int n = s1.length(), i = 0;
            char op = '+'; // 初始化为 + 号, 为了统一操作: 加入第一个数
            char[] s = s1.toCharArray();

            while (i < n) {
                // 1. 碰见空格, 忽略
                if (s[i] == ' ') i++;
                    // 2. 碰见数字
                else if (s[i] >= '0' && s[i] <= '9') {
                    // 提取出数字(有可能是两位或者三位数)
                    int tmp = 0;
                    while (i < n && s[i] >= '0' && s[i] <= '9') {
                        tmp = tmp * 10 + s[i] - '0';
                        i++;
                    }
                    // 提取之后, 判断当前数字前面的符号, 根据符号入栈
                    if (op == '+') stack.push(tmp);
                    else if (op == '-') stack.push(-tmp);
                    else if (op == '*') {
                        // stack.peek() * tmp; 泛型是 Integer, 不是引用类型, 所以不能用 peek, 指向的不是同一个地址
                        // 下一个题中的 泛型是 StringBuffer 就可以
                        stack.push(stack.pop() * tmp);
                    }
                    // else stack.peek() / tmp;
                    else stack.push(stack.pop() / tmp);
                    // i 已经执行非数字了, 所以不用 i++ 了
                    // 3. 碰见符号了, 直接更新
                } else {
                    op = s[i];
                    i++;
                }
            }
            // 遍历完之后, 把栈里的元素进行相加
            int ret = 0;
            while (!stack.isEmpty()) {
                ret += stack.pop();
            }
            return ret;
        }
    }
}
